package private

import (
	"dc-go/global"
	"dc-go/model"
	"dc-go/utils"
	"encoding/json"
	"errors"
	"sort"

	"github.com/gin-gonic/gin"
)

type ServiceUser struct{}

func (s *ServiceUser) GetUserList(requestUserList model.RequestGetUserList) (user interface{}, total int64, err error) {
	if requestUserList.SortBy == "" {
		requestUserList.SortBy = "id"
		requestUserList.Desc = false
	}
	pageSize := requestUserList.PageSize
	offset := requestUserList.PageSize * (requestUserList.Page - 1)
	db := global.DcDb.Model(&model.SysUser{})
	var userList []model.SysUser
	//配置搜索
	if requestUserList.EmpeeAcct != "" {
		db = db.Where("empee_acct like ?", "%"+requestUserList.EmpeeAcct+"%")
	}
	if requestUserList.StaffName != "" {
		db = db.Where("staff_name like ?", "%"+requestUserList.StaffName+"%")
	}
	if requestUserList.Mobile != "" {
		db = db.Where("mobile like ?", "%"+requestUserList.Mobile+"%")
	}
	if requestUserList.Status != "" {
		db = db.Where("status = ?", requestUserList.Status)
	}
	if requestUserList.Source != "" {
		db = db.Where("source = ?", requestUserList.Source)
	}

	err = db.Count(&total).Error
	if err != nil {
		return nil, 0, err
	}
	err = db.Limit(pageSize).Offset(offset).Order(model.OrderByColumn(requestUserList.SortBy, requestUserList.Desc)).
		Preload("OrgRole.Role").Preload("OrgRole.Org").Find(&userList).Error
	return userList, total, err

}

func (s *ServiceUser) QueryUserByEmpeeAcct(empee_acct string) (userInfo model.SysUser, err error) {
	var user model.SysUser
	err = global.DcDb.Preload("OrgRole.Role").Preload("OrgRole.Org").First(&user, "empee_acct = ?", empee_acct).Error
	return user, err
}

func (s *ServiceUser) QueryUserById(id uint) (userInfo model.SysUser, err error) {
	var user model.SysUser
	err = global.DcDb.
		Preload("Role").Preload("OrgRole.Role").Preload("OrgRole.Org").First(&user, "id = ?", id).Error
	return user, err
}

func (s *ServiceUser) ResetPasswordToDefaultById(id uint) (defaultPassword string, err error) {
	var sysUser model.SysUser
	if err = global.DcDb.Where("id = ?", id).First(&sysUser).Error; err != nil {
		return "", err
	}
	defaultPassword = utils.GetConfigBackend("defaultPassword")
	var pwd string
	if defaultPassword == "" {
		pwd = utils.EncodeMD5("123456")
	} else {
		pwd = utils.EncodeMD5(defaultPassword)
	}
	err = global.DcDb.Model(&sysUser).Update("password", pwd).Error
	if err != nil {
		return "", err
	}
	err = global.DcDb.Exec("update manage.sys_user set password = ? where user_id = ?", pwd, id).Error
	if err != nil {
		return "", err
	}
	return
}

func (s *ServiceUser) GetUserMenu(c *gin.Context) (menu []model.SysMenu, err error) {
	empee_acct := utils.GetEmpeeAcct(c)
	var user model.SysUser
	err = global.DcDb.Where("empee_acct=?", empee_acct).Preload("OrgRole").First(&user).Error
	if err != nil {
		return nil, err
	}
	var orgRoles []model.SysOrgRole
	err = global.DcDb.Model(&user).Association("OrgRole").Find(&orgRoles)
	if err != nil {
		return nil, err
	}
	roleCodes := make([]string, 0)
	for _, v := range orgRoles {
		roleCodes = append(roleCodes, v.RoleCode)
	}
	var roleMenus []model.SysRoleMenu
	err = global.DcDb.Where("role_code in (?)", roleCodes).Find(&roleMenus).Error
	if err != nil {
		return nil, err
	}
	//这里不使用Association("Menu")是因为要Preload("Sql")
	menuCodes := make([]string, 0)
	for _, v := range roleMenus {
		menuCodes = append(menuCodes, v.MenuCode)
	}
	var menus []model.SysMenu
	err = global.DcDb.Where("menu_code in (?)", menuCodes).Where("hidden != 'yes'").Preload("Sql").Find(&menus).Error
	if err != nil {
		return nil, err
	}
	//menus切片去重
	type distinctMenu []model.SysMenu
	resultMenu := map[string]bool{}
	for _, v := range menus {
		data, _ := json.Marshal(v)
		resultMenu[string(data)] = true
	}
	result := distinctMenu{}
	for mm := range resultMenu {
		var m model.SysMenu
		_ = json.Unmarshal([]byte(mm), &m)
		result = append(result, m)
	}
	//result切片排序
	sort.Slice(result, func(i, j int) bool {
		return result[i].Sort < result[j].Sort
	})
	return result, nil
}

func (s *ServiceUser) ChangePassword(empee_acct string, toChangePassword model.RequestChangePassword) (err error) {
	if toChangePassword.NewPassword1 != toChangePassword.NewPassword2 {
		return errors.New("两次新密码不一致! ")
	}
	var sysUser model.SysUser
	if err = global.DcDb.Where("empee_acct = ?", empee_acct).First(&sysUser).Error; err != nil {
		return err
	}
	oldPassword := utils.EncodeMD5(toChangePassword.OldPassword)
	if sysUser.Password != oldPassword {
		return errors.New("旧密码错误! ")
	}
	newPassword := utils.EncodeMD5(toChangePassword.NewPassword1)
	if oldPassword == newPassword {
		return errors.New("新旧密码是一样的! ")
	}
	err = global.DcDb.Model(&sysUser).Update("password", newPassword).Error
	if err != nil {
		return err
	}
	err = global.DcDb.Exec("update manage.sys_user set password = ? where user_name = ?", newPassword, empee_acct).Error
	if err != nil {
		return err
	}
	return err
}
